import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;

/**
 * sdk请求客户端
 */
public class SDKClient {
    /**
     * 唯一实例
     */
    private static SDKClient instance = null;

    /**
     * appkey
     */
    private final String mAppKey;

    private final String mAppSecret;

    /**
     * 网关地址
     */
    private String mApiUrl = "https://openapi.huatuitui.com";

    /**
     * @param appKey    String
     * @param appSecret String
     * @param apiUrl    String
     */
    public SDKClient(String appKey, String appSecret, String apiUrl) {
        mAppKey = appKey;
        mAppSecret = appSecret;
        if (!apiUrl.isEmpty()) {
            mApiUrl = apiUrl;
        }
    }

    /**
     * 返回一个实例
     *
     * @return SDKClient
     */
    public static SDKClient getInstance(String appKey, String appSecret, String apiUrl) {
        if (instance == null) {
            instance = new SDKClient(appKey, appSecret, apiUrl);
        }
        return instance;
    }


    /**
     * 请求一个接口
     *
     * @param apiName String
     * @param params HashMap<String, Object>
     * @return String
     */
    public String executeApi(String apiName, HashMap<String, Object> params) {
        String timer = String.valueOf(System.currentTimeMillis() / 1000);
        params.put("app_key", mAppKey);
        params.put("api_name", apiName);
        params.put("time", timer);
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);

        StringBuilder paramString = new StringBuilder();
        for (String key : keys) {
            if (params.get(key).equals("")) {
                continue;
            }
            String value;
            try {
                value = URLEncoder.encode(params.get(key).toString(), "UTF-8")
                        .replace("*", "%2A");
            } catch (UnsupportedEncodingException e) {
                continue;
                //e.printStackTrace();
            }
            if (paramString.length() == 0) {
                paramString.append(key).append("=").append(value);
            } else {
                paramString.append("&").append(key).append("=").append(value);
            }
        }
        String sign = MD5(paramString.toString() + mAppSecret);
        params.put("sign", sign);
        String data = "";
        try {
            data = HttpUtil.httpPostRequest(mApiUrl, params);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return data;

    }

    /**
     * MD5加密算法
     *
     * @param s String
     * @return String
     * @see [类、类#方法、类#成员]
     */
    private String MD5(String s) {
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            byte[] btInput = s.getBytes(StandardCharsets.UTF_8);
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            int j = md.length;
            char[] str = new char[j * 2];
            int k = 0;
            for (byte byte0 : md) {
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str).toLowerCase();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
